Firebase AI Logic 在 2025 年以及 2026 年的大部分時間裡都不支援文字轉語音(Text-to-Speech),因此我舊的專案建立了一個 Firebase Cloud Function 來呼叫 Gemini API,以便將文字轉換為語音。接著,Angular 應用程式呼叫該雲端函式以取得 WAV 格式的原始二進位資料,並將其指派給 HTML audio 元素的 src 屬性。使用者點擊該元素的播放按鈕即可聆聽語音。
我曾請 Gemini CLI 使用 TailwindCSS V4 類別來設定元件樣式,因此外觀看起來不算太糟。然而,它缺乏完整的設計系統(Design System)。
該專案分為兩個部分:一個 Angular 用戶端和一些 Firebase Cloud Functions。由於缺乏完善的 DevOps 背景,我無法將它們部署到雲端,只能在 localhost 本地端進行測試。
8 月份時,Firebase AI Logic 終於支援了文字轉語音,時間點恰到好處。
我可以透過一個全新的(greenfield)Angular 專案重新打造它,並利用 AI 來解決我的許多痛點:
首先,我建立了一個新的 Angular 專案,並選擇了 CSS 和 TailwindCSS 函式庫。
ng new ng-firebase-tts
Angular 編譯器安裝了依賴項,並至少為 TailwindCSS 和 Prettier 建立了設定檔鷹架。
在 .prettierrc 中,我喜歡將 printWidth 從 100 增加到 120,並在 package.json 中新增一個 format 指令稿來格式化工作區中的檔案。
{
"printWidth": 120,
"singleQuote": true,
"trailingComma": "all",
"semi": true,
"overrides": [
{
"files": "*.html",
"options": {
"parser": "angular"
}
}
]
}
"scripts": {
"ng": "ng",
"start": "ng serve",
"format": "prettier --write \"**/*.{ts,js,mjs,json,html}\""
},
第二步,我安裝了額外的開發依賴項,並建構了一個工作流程(pipeline)來自動化維護程式碼品質、修正格式並標準化 commit 訊息。
cd ng-firebsae-tts
ng add angular-eslint
angular-eslint 原理圖(schematics)安裝了 eslint 並為我生成了 eslint.config.js。接著,我提示 AI 將 eslint.config.js 遷移至 eslint.config.mjs,這樣我就可以使用 eslint-plugin-unicorn 依賴項中的 unicorn/prefer-switch 規則。
cd ng-firebase-tts
agy
提示詞(Prompt):
Please migrate @eslint.config.js to @eslint.config.mjs
之後,我安裝了 eslint-plugin-unicorn、lintstaged、husky、@commitlint/cli 以及 @commitlint/config-conventional:
npm i --save-exact --save-dev eslint-plugin-unicorn lintstaged husky @commitlint/cli@commitlint/cli
接著,我更新了 tsconfig.json 以新增 resolveJsonModule 和 paths。resolveJsonModule: true 允許 Angular 程式碼直接讀取 JSON 檔案中的值。新增 paths 後,import 路徑的檔案路徑就可以改用 @/ 開頭,而非相對路徑。
{
"compilerOptions": {
"resolveJsonModule": true,
"paths": {
"@/*": ["./src/app/*"],
"@/public/*": ["./public/*"]
}
}
}
您可以在 ESLint 設定檔 中找到這些 ESLint 規則。
一些有代表性的規則:
| 規則名稱 | 描述 |
|---|---|
| unicorn/prefer-switch | 使用 switch 取代多個 if-else if-else 分支 |
| no-restricted-imports | 禁止使用相對路徑,例如 ../, ../../ |
| complexity | 禁止複雜函式 |
| max-lines-per-function | 函式行數保持在 40 行或以內。簡短的函式更容易理解 |
| max-lines | 每個檔案行數保持在 300 行或以內。當檔案過長時,其承擔的職責往往超過應有範圍 |
在完成 ESLint 遷移後,顯而易見的選擇是為 commitlint 與 lintstaged 建立 mjs 設定檔。接著,新增 pre-commit 和 commit-msg husky 鉤子(hooks)。
commitlint.config.mjs 和 lint-staged.config.mjs 都非常簡短。
最精簡的 commitlint.config.mjs 只有 3 行。
export default {
extends: ['@commitlint/config-conventional'],
};
lint-staged.config.js 可修復 ESLint 錯誤並格式化暫存(staged)檔案。
export default {
'*.{ts,js,mjs,html}': ['eslint --fix', 'prettier --write'],
'*.{json,css,md}': ['prettier --write'],
};
最後一步是開啟終端機以初始化 husky 並新增鉤子。
npx husky init
該指令會建立一個 .husky/pre-commit 檔案。開啟它並刪除所有內容。
npx --no lint-staged
建立 commitlint 鉤子:
echo "npx --no -- commitlint --edit \$1" > .husky/commit-msg
第 2 天到此結束。安裝 eslint、prettier、lint-staged、husky 和 commitlint 等開發依賴項本身或許平淡無奇,但在開啟一個新專案時,這是一個至關重要的階段。這正是具備企業級水準的系統與脆弱原型之間的劃時代分水嶺。
相關資源:
Angular ESLint
Commitlint
Husky
Lintstaged
ESLint
eslint-plugin-unicorn
設定 commit-msg 鉤子